package main

import (
	"fmt"
	"reflect"
)

/*
   Call()方法：
   通过反射，调用方法
 */

type Person struct {
	Name string
	Age int
	Sex string
}

func (p Person)Say(msg string)  {
	fmt.Println("hello，",msg)
}
func (p Person)PrintInfo()  {
	fmt.Printf("姓名：%s,年龄：%d，性别：%s\n",p.Name,p.Age,p.Sex)
}

func (p Person) Test(i,j int,s string){
	fmt.Println(i,j,s)
}

func main() {

	person := Person{"Ruby",30,"男"}

	// 1. 要通过反射来调用起对应的方法，必须要先通过reflect.ValueOf(interface)来获取到reflect.Value，
	// 得到“反射类型对象”后才能做下一步处理
	valueOf := reflect.ValueOf(person)

	// 2.一定要指定参数为正确的方法名
	// 先看看没有参数的调用方法
	printInfoMethod := valueOf.MethodByName("PrintInfo")
	fmt.Printf("Kind : %s, Type : %s\n",printInfoMethod.Kind(),printInfoMethod.Type())
	// //没有参数，直接写nil
	printInfoMethod.Call(nil)

	sayMethod := valueOf.MethodByName("Say")
	fmt.Printf("Kind : %s, Type : %s\n",sayMethod.Kind(),sayMethod.Type())

	sayArgs := [] reflect.Value{reflect.ValueOf("反射机制")}
	sayMethod.Call(sayArgs)

	testMethod := valueOf.MethodByName("Test")
	fmt.Printf("Kind : %s, Type : %s\n",testMethod.Kind(),testMethod.Type())

	testArgs :=[] reflect.Value{reflect.ValueOf(10), reflect.ValueOf(20),reflect.ValueOf("args")}
	testMethod.Call(testArgs)

}
